package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"text/template"
)

const HTTP_GET_MAX_SIZE = 2 * 1024 * 1024

type UfopPostBody struct {
	Cmd string `json:"cmd"`
	Src struct {
		URL      string `json:"url"`
		Mimetype string `json:"mimetype"`
		Fsize    int    `json:"fsize"`
		Bucket   string `json:"bucket"`
		Key      string `json:"key"`
	} `json:"src"`
}

func httpGet(url string) (body []byte, err error) {
	res, err := http.Get(url)
	if err != nil {
		return nil, fmt.Errorf("httpGet error: %s", err)
	}
	defer res.Body.Close()
	body, err = ioutil.ReadAll(http.MaxBytesReader(nil, res.Body, HTTP_GET_MAX_SIZE))
	if err != nil {
		return nil, fmt.Errorf("httpGet read body error: %s", err)
	}
	return
}

func handler(rw http.ResponseWriter, req *http.Request) {
	var err error
	var bodyString, bodyStringPretty, originData []byte
	var url string

	defer func() {
		if err != nil {
			http.Error(rw, err.Error(), 500)
		}
	}()

	defer req.Body.Close()

	bodyString, err = ioutil.ReadAll(req.Body)
	if err != nil {
		log.Printf("handler body read error: %s\n", err.Error())
		return
	}

	body := &UfopPostBody{}
	err = json.Unmarshal(bodyString, &body)
	if err != nil {
		log.Printf("handler body unmarshal error: %s\n", err.Error())
		return
	}

	bodyStringPretty, err = json.MarshalIndent(body, "", "    ")
	if err != nil {
		log.Printf("handler body marshal error: %s\n", err.Error())
		return
	}

	url = body.Src.URL
	originData, err = httpGet(url)
	if err != nil {
		log.Printf("handler http get error:", err.Error())
	}

	tpl, err := template.New("res").Parse(`
req body:
-------------
{{.bodyString}}
req file:
-------------
{{.originData}}
		`)
	if err != nil {
		panic("")
	}
	if len(originData) > 2048 {
		originData = originData[:2048]
	}
	brw := bufio.NewWriter(rw)
	tpl.Execute(brw, map[string]string{
		"bodyString": string(bodyStringPretty),
		"originData": string(originData),
	})
	brw.Flush()
}

func main() {
	http.HandleFunc("/uop", handler)
	log.Fatalln(http.ListenAndServe(":9100", nil))
}
